package cn.iocoder.yudao.module.resource.service.cosplay;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.redis.core.RedisPublishClient;
import cn.iocoder.yudao.module.infra.service.file.FileService;
import cn.iocoder.yudao.module.infra.service.file.UploadFileResult;
import cn.iocoder.yudao.module.resource.api.model.CosplayDTO;
import cn.iocoder.yudao.module.resource.common.LmrobotResourceConfig;
import cn.iocoder.yudao.module.resource.common.MemoryCacheService;
import cn.iocoder.yudao.module.resource.common.event.RoleUpdateEvent;
import cn.iocoder.yudao.module.resource.controller.admin.cosplay.vo.LmCosplayPageReqVO;
import cn.iocoder.yudao.module.resource.controller.admin.cosplay.vo.LmCosplayRespVO;
import cn.iocoder.yudao.module.resource.controller.admin.cosplay.vo.LmCosplaySaveReqVO;
import cn.iocoder.yudao.module.resource.controller.admin.tag.vo.TagRespVO;
import cn.iocoder.yudao.module.resource.dal.dataobject.audiotone.AudioToneDO;
import cn.iocoder.yudao.module.resource.dal.dataobject.cosplay.LmCosplayDO;
import cn.iocoder.yudao.module.resource.dal.dataobject.tag.TagDO;
import cn.iocoder.yudao.module.resource.dal.mysql.cosplay.LmCosplayMapper;
import cn.iocoder.yudao.module.resource.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.resource.service.audiotone.AudioToneService;
import cn.iocoder.yudao.module.resource.service.tag.TagService;
import com.alibaba.fastjson.JSON;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 角色 Service 实现类
 *
 * @author wgs
 */
@Service
@Slf4j
@Validated
public class LmCosplayServiceImpl extends MemoryCacheService<Integer, LmCosplayDO> implements LmCosplayService, ApplicationListener<RoleUpdateEvent> {

    @Resource
    private LmCosplayMapper cosplayMapper;
    @Resource
    private FileService fileService;
    @Resource
    private TagService tagService;
    @Resource
    private AudioToneService audioToneService;

    public LmCosplayServiceImpl(LmrobotResourceConfig resourceConfig) {
        super(resourceConfig);
    }

    @Override
    public void onApplicationEvent(RoleUpdateEvent event) {
        log.info("收到角色更新事件,roleId:{}", event.getRoleId());
        this.delete(event.getRoleId());
    }

    @Override
    protected LmCosplayDO loadEntity(Integer key) {
        return cosplayMapper.selectById(key);
    }

    @Override
    public Integer createCosplay(LmCosplaySaveReqVO createReqVO) {
        // 插入
        LmCosplayDO cosplay = BeanUtils.toBean(createReqVO, LmCosplayDO.class);
        if (createReqVO.getAudioIdList() != null) {
            cosplay.setAudioArray(JSON.toJSONString(createReqVO.getAudioIdList()));
        }
        cosplayMapper.insert(cosplay);
        // 返回
        return cosplay.getId();
    }

    @Override
    public void updateCosplay(LmCosplaySaveReqVO updateReqVO) {
        // 校验存在
        validateCosplayExists(updateReqVO.getId());
        // 更新
        LmCosplayDO updateObj = BeanUtils.toBean(updateReqVO, LmCosplayDO.class);
        if (updateReqVO.getAudioIdList() != null) {
            updateObj.setAudioArray(JSON.toJSONString(updateReqVO.getAudioIdList()));
        }
        cosplayMapper.updateById(updateObj);
        cosplayMapper.updateFieldNull(updateObj);
        RedisPublishClient redisPublishClient = SpringUtil.getBean(RedisPublishClient.class);
        RoleUpdateEvent roleUpdateEvent = new RoleUpdateEvent();
        roleUpdateEvent.setRoleId(updateReqVO.getId());
        redisPublishClient.publishMsg(roleUpdateEvent);
    }

    @Override
    public void deleteCosplay(Integer id) {
        // 校验存在
        validateCosplayExists(id);
        // 删除
        cosplayMapper.deleteById(id);
    }

    @Override
    public void validateCosplayExists(Integer id) {
        if (cosplayMapper.selectById(id) == null) {
            throw exception(ErrorCodeConstants.COSPLAY_NOT_EXISTS);
        }
    }

    @Override
    public LmCosplayDO getCosplay(Integer id) {
        LmCosplayDO cosplayDO = this.getFromCacheByKey(id);
        return cosplayDO;
    }

    @Override
    public PageResult<LmCosplayDO> getCosplayPage(LmCosplayPageReqVO pageReqVO) {
        return cosplayMapper.selectPage(pageReqVO);
    }

    @Override
    public void setLmCosplayResp(LmCosplayRespVO cosplayResp) {
        if (cosplayResp == null) {
            return;
        }

        attachVORelationUrl(Arrays.asList(cosplayResp));

        if (cosplayResp.getTagArray() != null) {
            List<Integer> tagIdArray = JSON.parseArray(cosplayResp.getTagArray(), Integer.class);
            List<TagDO> tagList = tagService.getTagList(tagIdArray);
            List<TagRespVO> tagRespVOS = BeanUtils.toBean(tagList, TagRespVO.class);
            cosplayResp.setTagArrayVo(tagRespVOS);
        }

        if (cosplayResp.getAudioToneId() != null) {
            AudioToneDO audioTone = audioToneService.getAudioTone(cosplayResp.getAudioToneId());
            if (audioTone != null) {
                cosplayResp.setAudioToneName(audioTone.getName());
                UploadFileResult uploadFileResult = fileService.getFile(audioTone.getFileId(), 600);
                if (uploadFileResult != null) {
                    cosplayResp.setVoiceUrl(uploadFileResult.getFileUrl());
                }
            }
        }
    }

    @Override
    public void attachVORelationUrl(List<LmCosplayRespVO> vos) {
        if (CollUtil.isEmpty(vos)) {
            return;
        }

        final Collection<Long> fileIdList = new HashSet<>();
        for (LmCosplayRespVO vo : vos) {
            if (vo.getRoleImageId() != null) {
                fileIdList.add(vo.getRoleImageId());
            }
            if (vo.getRoleIconId() != null) {
                fileIdList.add(vo.getRoleIconId());
            }
            if (vo.getRoleVideoId() != null) {
                fileIdList.add(vo.getRoleVideoId());
            }
        }
        if (CollUtil.isEmpty(fileIdList)) {
            return;
        }

        final List<UploadFileResult> fileResults = fileService.getFile(fileIdList, null);
        if (CollUtil.isEmpty(fileResults)) {
            return;
        }
        final Map<Long, UploadFileResult> fileId2FileResult = fileResults.stream().collect(Collectors.toMap(UploadFileResult::getFileId, c -> c, (v1, v2) -> v1));

        for (LmCosplayRespVO vo : vos) {
            if (vo.getRoleImageId() != null) {
                vo.setRoleImage(fileId2FileResult.get(vo.getRoleImageId()));
            }
            if (vo.getRoleIconId() != null) {
                vo.setRoleIcon(fileId2FileResult.get(vo.getRoleIconId()));
            }
            if (vo.getRoleVideoId() != null) {
                vo.setRoleVideo(fileId2FileResult.get(vo.getRoleVideoId()));
            }
        }
    }

    @Override
    public void attachDTORelationUrl(List<CosplayDTO> vos) {
        if (CollUtil.isEmpty(vos)) {
            return;
        }

        final Collection<Long> fileIdList = new HashSet<>();
        for (CosplayDTO vo : vos) {
            if (vo.getRoleImageId() != null) {
                fileIdList.add(vo.getRoleImageId());
            }
            if (vo.getRoleIconId() != null) {
                fileIdList.add(vo.getRoleIconId());
            }
            if (vo.getRoleVideoId() != null) {
                fileIdList.add(vo.getRoleVideoId());
            }
        }
        if (CollUtil.isEmpty(fileIdList)) {
            return;
        }

        final List<UploadFileResult> fileResults = fileService.getFile(fileIdList, null);
        if (CollUtil.isEmpty(fileResults)) {
            return;
        }
        final Map<Long, UploadFileResult> fileId2FileResult = fileResults.stream().collect(Collectors.toMap(UploadFileResult::getFileId, c -> c, (v1, v2) -> v1));

        for (CosplayDTO vo : vos) {
            if (vo.getRoleImageId() != null) {
                vo.setRoleImage(BeanUtils.toBean(fileId2FileResult.get(vo.getRoleImageId()), CosplayDTO.UploadFileResult.class));
            }
            if (vo.getRoleIconId() != null) {
                vo.setRoleIcon(BeanUtils.toBean(fileId2FileResult.get(vo.getRoleIconId()), CosplayDTO.UploadFileResult.class));
            }
            if (vo.getRoleVideoId() != null) {
                vo.setRoleVideo(BeanUtils.toBean(fileId2FileResult.get(vo.getRoleVideoId()), CosplayDTO.UploadFileResult.class));
            }
        }
    }
}